anywidget-graph¶
Interactive graph visualization widget for Python notebooks.
Overview¶
anywidget-graph provides interactive graph visualization powered by Sigma.js. Built on the anywidget framework, it works universally across Jupyter, Marimo, VS Code, Colab, and Databricks with support for multiple graph database backends.
Features¶
Multi-Backend Support¶
| Backend | Query Languages |
|---|---|
| Grafeo | GQL, Cypher, SPARQL, Gremlin, GraphQL |
| Neo4j | Cypher |
| ArangoDB | AQL |
| LadybugDB | Cypher |
| NetworkX | Python API |
Query Language Converters¶
Automatically converts query results from:
- Cypher (Neo4j, Grafeo)
- GQL (ISO standard)
- SPARQL (RDF/semantic web)
- Gremlin (TinkerPop)
- GraphQL (JSON responses)
- AQL (ArangoDB)
Interactivity¶
- Pan, zoom, and navigate
- Click nodes/edges to select
- Expand/collapse neighbors
- Multi-select paths
- Export to PNG, SVG, JSON
Installation¶
With optional backends:
Quick Start¶
From Grafeo¶
from anywidget_graph import Graph
from grafeo import GrafeoDB
db = GrafeoDB()
db.execute("""
INSERT (:Person {name: 'Alice'})-[:KNOWS]->(:Person {name: 'Bob'}),
(:Person {name: 'Bob'})-[:KNOWS]->(:Person {name: 'Carol'})
""")
result = db.execute("MATCH (n)-[r]->(m) RETURN n, r, m")
graph = Graph.from_grafeo(result)
graph
From NetworkX¶
import networkx as nx
from anywidget_graph import Graph
G = nx.karate_club_graph()
widget = Graph.from_networkx(G)
widget
From Edge List¶
from anywidget_graph import Graph
nodes = [
{"id": "1", "label": "Alice", "group": "person"},
{"id": "2", "label": "Bob", "group": "person"},
{"id": "3", "label": "Acme", "group": "company"},
]
edges = [
{"source": "1", "target": "2", "label": "knows"},
{"source": "2", "target": "3", "label": "works_at"},
]
widget = Graph(nodes=nodes, edges=edges)
widget
Styling¶
Node Styling¶
widget = Graph(
nodes=nodes,
edges=edges,
node_color_by="group",
node_size_by="degree",
node_colors={
"person": "#6366f1",
"company": "#22c55e"
}
)
Layout Algorithms¶
Event Handling¶
@widget.on_node_click
def handle_node_click(node_id, node_data):
print(f"Clicked: {node_data['label']}")
@widget.on_edge_click
def handle_edge_click(edge_id, edge_data):
print(f"Edge: {edge_data['label']}")
Configuration¶
widget = Graph(
nodes=nodes,
edges=edges,
# Display
show_labels=True,
show_edge_labels=False,
show_toolbar=True,
dark_mode=True,
# Layout
layout="force",
# Performance
virtualize=True, # For 1000+ nodes
)
Database Connections¶
Neo4j¶
from anywidget_graph import Graph
from anywidget_graph.backends import Neo4jBackend
backend = Neo4jBackend(
uri="bolt://localhost:7687",
user="neo4j",
password="password"
)
widget = Graph(
backend=backend,
query="MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 100"
)
ArangoDB¶
from anywidget_graph.backends import ArangoDBBackend
backend = ArangoDBBackend(
host="localhost",
database="mydb",
username="root",
password="password"
)
widget = Graph(
backend=backend,
query="FOR v, e IN 1..2 OUTBOUND 'nodes/1' edges RETURN {v, e}"
)
Notebook Compatibility¶
Works in any environment supporting anywidget:
- JupyterLab / Jupyter Notebook
- Marimo
- VS Code Notebooks
- Google Colab
- Databricks
Requirements¶
- Python 3.12+
- Modern browser
License¶
Apache-2.0